Popular Searches
Popular Course Categories
Popular Courses

Introduction to JavaScriptExecutor

Introduction to JavaScriptExecutor

JavaScript with Selenium

<div class="selenium-notes">

<h1>Introduction to JavaScriptExecutor in Selenium WebDriver</h1>

<p>JavaScriptExecutor is an important Selenium WebDriver interface that allows Java-based Selenium automation scripts to execute JavaScript code directly inside the browser. It is especially useful when working with modern JavaScript-based applications where elements are dynamically created, updated, hidden, scrolled, or controlled by client-side JavaScript.</p>

<p>In normal Selenium automation, testers interact with web elements using WebDriver methods such as <code>click()</code>, <code>sendKeys()</code>, <code>getText()</code>, and <code>clear()</code>. JavaScriptExecutor provides an additional mechanism for interacting with or inspecting the browser's DOM when a particular browser-side operation requires JavaScript.</p>

<p>JavaScriptExecutor is commonly used for scrolling, reading DOM properties, checking page readiness, highlighting elements during debugging, executing browser-side scripts, interacting with specialized application behavior, and performing certain diagnostic operations.</p>

<p><a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training Course</a> | <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Register for Course Demo</a></p>

<hr>

<h2>1. What is JavaScriptExecutor?</h2>

<p><code>JavascriptExecutor</code> is a Selenium WebDriver interface that provides methods for executing JavaScript code in the context of the currently loaded web page.</p>

<pre><code>Java Selenium Test

      ↓

JavascriptExecutor

      ↓

JavaScript Code

      ↓

Browser

      ↓

DOM / Web Page</code></pre>

<p>It acts as a bridge between a Java Selenium program and JavaScript running inside the browser.</p>

<hr>

<h2>2. Why Do We Need JavaScriptExecutor?</h2>

<p>Most Selenium operations can be performed directly through WebDriver. However, some web applications have complex JavaScript behavior, dynamic DOM updates, custom controls, or browser-side properties that may require JavaScript for inspection or specialized interaction.</p>

<ul>

<li>Scroll to an element.</li>

<li>Scroll to the top or bottom of a page.</li>

<li>Read JavaScript DOM properties.</li>

<li>Check document readiness.</li>

<li>Highlight an element for debugging.</li>

<li>Inspect element properties.</li>

<li>Read or modify certain DOM properties.</li>

<li>Execute browser-side JavaScript.</li>

<li>Perform controlled DOM-level operations.</li>

<li>Assist with debugging dynamic applications.</li>

</ul>

<hr>

<h2>3. JavaScriptExecutor Interface</h2>

<p>The Selenium interface is named <code>JavascriptExecutor</code>.</p>

<pre><code>import org.openqa.selenium.JavascriptExecutor;</code></pre>

<p>It is generally obtained by casting the WebDriver instance.</p>

<pre><code>JavascriptExecutor js =

    (JavascriptExecutor) driver;</code></pre>

<hr>

<h2>4. Basic Syntax</h2>

<pre><code>JavascriptExecutor js =

    (JavascriptExecutor) driver;

 

js.executeScript("JavaScript code");</code></pre>

<hr>

<h2>5. Complete Basic Example</h2>

<pre><code>import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

 

public class JavaScriptExample {

 

    public static void main(String[] args) {

 

        WebDriver driver = new ChromeDriver();

 

        driver.get("https://example.com");

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        js.executeScript(

            "alert('Hello from Selenium');"

        );

 

        driver.quit();

    }

}</code></pre>

<hr>

<h2>6. How JavaScriptExecutor Works</h2>

<pre><code>WebDriver

   ↓

Cast Driver to JavascriptExecutor

   ↓

executeScript()

   ↓

Browser JavaScript Engine

   ↓

JavaScript Executes

   ↓

Result Returned to Java</code></pre>

<hr>

<h2>7. executeScript() Method</h2>

<p>The <code>executeScript()</code> method executes JavaScript synchronously in the current browsing context.</p>

<pre><code>Object result = js.executeScript(

    "return document.title;"

);</code></pre>

<p>The return type is generally <code>Object</code>, so the result may need to be cast to the expected Java type.</p>

<hr>

<h2>8. executeAsyncScript() Method</h2>

<p><code>executeAsyncScript()</code> is used when JavaScript execution involves asynchronous behavior. The browser-side script must signal completion through the callback supplied by Selenium.</p>

<pre><code>Object result = js.executeAsyncScript(

    "var callback = arguments[arguments.length - 1];" +

    "setTimeout(function() {" +

    "callback('Completed');" +

    "}, 1000);"

);</code></pre>

<hr>

<h2>9. Difference Between executeScript() and executeAsyncScript()</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>executeScript()</th><th>executeAsyncScript()</th></tr>

<tr><td>Used for synchronous JavaScript</td><td>Used for asynchronous JavaScript</td></tr>

<tr><td>Returns after script execution</td><td>Waits for callback completion</td></tr>

<tr><td>Simple DOM operations</td><td>Async browser-side operations</td></tr>

<tr><td>Usually simpler</td><td>Requires callback handling</td></tr>

</table>

<hr>

<h2>10. The Importance of the return Keyword</h2>

<p>When a JavaScript value needs to be returned to Java, use the JavaScript <code>return</code> statement.</p>

<pre><code>String title = (String) js.executeScript(

    "return document.title;"

);</code></pre>

<p>Without <code>return</code>, a value that is calculated by the script is not automatically returned to the Java program.</p>

<hr>

<h2>11. Reading the Page Title</h2>

<pre><code>String title = (String) js.executeScript(

    "return document.title;"

);

 

System.out.println(title);</code></pre>

<hr>

<h2>12. Reading the Current URL</h2>

<pre><code>String url = (String) js.executeScript(

    "return window.location.href;"

);

 

System.out.println(url);</code></pre>

<hr>

<h2>13. Reading Document Ready State</h2>

<pre><code>String state = (String) js.executeScript(

    "return document.readyState;"

);

 

System.out.println(state);</code></pre>

<p>Typical values include <code>loading</code>, <code>interactive</code>, and <code>complete</code>.</p>

<hr>

<h2>14. Waiting for Document Ready State</h2>

<pre><code>WebDriverWait wait =

    new WebDriverWait(driver, Duration.ofSeconds(15));

 

wait.until(driver -&gt;

    ((JavascriptExecutor) driver)

        .executeScript("return document.readyState")

        .equals("complete")

);</code></pre>

<p>This can be useful for document loading, but it does not guarantee that all JavaScript framework components or API-driven content have finished rendering.</p>

<hr>

<h2>15. Page Load vs JavaScript Application Readiness</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Document Ready</th><th>Application Ready</th></tr>

<tr><td>Browser document has reached a ready state</td><td>Application-specific components are ready</td></tr>

<tr><td>HTML/document loading is mostly complete</td><td>API calls may still be running</td></tr>

<tr><td>Useful for page-level synchronization</td><td>Requires application-specific conditions</td></tr>

</table>

<hr>

<h2>16. Using arguments[0]</h2>

<p>One of the most important concepts in JavaScriptExecutor is the <code>arguments</code> object. Selenium can pass Java objects such as WebElements into JavaScript.</p>

<pre><code>js.executeScript(

    "arguments[0].click();",

    element

);</code></pre>

<p>Here, <code>arguments[0]</code> represents the first argument passed to the JavaScript code.</p>

<hr>

<h2>17. Passing Multiple Arguments</h2>

<pre><code>js.executeScript(

    "arguments[0].value = arguments[1];",

    element,

    "Selenium"

);</code></pre>

<p><code>arguments[0]</code> represents the element and <code>arguments[1]</code> represents the string value.</p>

<hr>

<h2>18. JavaScript Click</h2>

<p>A JavaScript click can be performed using the DOM click method.</p>

<pre><code>js.executeScript(

    "arguments[0].click();",

    element

);</code></pre>

<hr>

<h2>19. WebElement click() vs JavaScript click()</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>WebElement.click()</th><th>JavaScript click()</th></tr>

<tr><td>Uses Selenium WebDriver interaction</td><td>Invokes DOM click through JavaScript</td></tr>

<tr><td>Preferred for normal user-like automation</td><td>Useful for specialized cases</td></tr>

<tr><td>Respects WebDriver interaction behavior</td><td>Can bypass some normal interaction checks</td></tr>

<tr><td>Should generally be the first choice</td><td>Should be used deliberately</td></tr>

</table>

<hr>

<h2>20. When Should JavaScript Click Be Used?</h2>

<ul>

<li>When a specific DOM-level interaction is required.</li>

<li>When debugging a difficult JavaScript-controlled component.</li>

<li>When the application requires a specialized browser-side operation.</li>

<li>When a carefully investigated UI issue requires a JavaScript workaround.</li>

</ul>

<p>Before using JavaScript click, investigate the actual reason a normal click fails.</p>

<hr>

<h2>21. Why JavaScript Click Should Not Be Used Everywhere</h2>

<p>Using JavaScript click for every button can hide genuine application or automation problems such as incorrect locators, overlays, invisible elements, disabled controls, incorrect frame context, or synchronization problems.</p>

<pre><code>Incorrect Approach:

Every click fails

      ↓

Use JavaScript click everywhere

 

Better Approach:

Click fails

      ↓

Check locator

      ↓

Check visibility

      ↓

Check overlay

      ↓

Check synchronization

      ↓

Check frame/window

      ↓

Use JS only if justified</code></pre>

<hr>

<h2>22. Scrolling Using JavaScript</h2>

<p>JavaScriptExecutor can scroll the browser viewport.</p>

<pre><code>js.executeScript(

    "window.scrollBy(0,500);"

);</code></pre>

<hr>

<h2>23. Scroll to the Bottom</h2>

<pre><code>js.executeScript(

    "window.scrollTo(0, document.body.scrollHeight);"

);</code></pre>

<hr>

<h2>24. Scroll to the Top</h2>

<pre><code>js.executeScript(

    "window.scrollTo(0, 0);"

);</code></pre>

<hr>

<h2>25. Scroll to a Specific Element</h2>

<pre><code>js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);</code></pre>

<p>Using <code>block:'center'</code> can position the element approximately in the center of the viewport.</p>

<hr>

<h2>26. JavaScript Scroll vs Selenium Actions Scroll</h2>

<pre><code>new Actions(driver)

    .scrollToElement(element)

    .perform();</code></pre>

<p>Both JavaScript and Selenium Actions can be used for scrolling. For normal user-like browser interaction, Selenium APIs are generally preferable; JavaScript provides additional control and is useful for specialized cases.</p>

<hr>

<h2>27. Highlighting an Element</h2>

<p>Selenium does not provide a dedicated native <code>highlight()</code> method. JavaScriptExecutor can temporarily modify an element's CSS for debugging.</p>

<pre><code>js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);</code></pre>

<hr>

<h2>28. Why Use outline Instead of border?</h2>

<p>An outline generally does not change the element's layout dimensions, making it convenient for temporary debugging highlights.</p>

<hr>

<h2>29. Highlighting with Background Color</h2>

<pre><code>js.executeScript(

    "arguments[0].style.backgroundColor='yellow';",

    element

);</code></pre>

<hr>

<h2>30. Highlighting with Multiple CSS Properties</h2>

<pre><code>js.executeScript(

    "arguments[0].style.outline='3px solid red';" +

    "arguments[0].style.backgroundColor='yellow';",

    element

);</code></pre>

<hr>

<h2>31. Highlighting Using a CSS Class</h2>

<pre><code>js.executeScript(

    "arguments[0].classList.add('selenium-highlight');",

    element

);</code></pre>

<hr>

<h2>32. Removing a Highlight</h2>

<pre><code>js.executeScript(

    "arguments[0].classList.remove('selenium-highlight');",

    element

);</code></pre>

<hr>

<h2>33. Reading Element Text</h2>

<pre><code>String text = (String) js.executeScript(

    "return arguments[0].innerText;",

    element

);

 

System.out.println(text);</code></pre>

<hr>

<h2>34. Reading textContent</h2>

<pre><code>String text = (String) js.executeScript(

    "return arguments[0].textContent;",

    element

);</code></pre>

<p><code>innerText</code> and <code>textContent</code> can behave differently because <code>innerText</code> is more closely related to rendered text while <code>textContent</code> reads the text content of the DOM node.</p>

<hr>

<h2>35. Reading an Attribute</h2>

<pre><code>String value = (String) js.executeScript(

    "return arguments[0].getAttribute('value');",

    element

);</code></pre>

<hr>

<h2>36. Reading a Data Attribute</h2>

<pre><code>String id = (String) js.executeScript(

    "return arguments[0].getAttribute('data-id');",

    element

);</code></pre>

<hr>

<h2>37. Reading the Input Value</h2>

<pre><code>String value = (String) js.executeScript(

    "return arguments[0].value;",

    input

);</code></pre>

<hr>

<h2>38. Checking Whether an Element Is Disabled</h2>

<pre><code>Boolean disabled = (Boolean) js.executeScript(

    "return arguments[0].disabled;",

    button

);

 

System.out.println(disabled);</code></pre>

<hr>

<h2>39. Checking Whether a Checkbox Is Selected</h2>

<pre><code>Boolean checked = (Boolean) js.executeScript(

    "return arguments[0].checked;",

    checkbox

);</code></pre>

<hr>

<h2>40. Reading the Element's Tag Name</h2>

<pre><code>String tagName = (String) js.executeScript(

    "return arguments[0].tagName;",

    element

);</code></pre>

<hr>

<h2>41. Reading the Element's Class Name</h2>

<pre><code>String className = (String) js.executeScript(

    "return arguments[0].className;",

    element

);</code></pre>

<hr>

<h2>42. Reading the Element ID</h2>

<pre><code>String id = (String) js.executeScript(

    "return arguments[0].id;",

    element

);</code></pre>

<hr>

<h2>43. Getting Element Coordinates</h2>

<p>The <code>getBoundingClientRect()</code> method can be used to inspect an element's position and dimensions.</p>

<pre><code>Object rect = js.executeScript(

    "return arguments[0].getBoundingClientRect();",

    element

);</code></pre>

<hr>

<h2>44. Checking Computed CSS</h2>

<pre><code>String display = (String) js.executeScript(

    "return window.getComputedStyle(arguments[0]).display;",

    element

);</code></pre>

<hr>

<h2>45. Checking Visibility Through JavaScript</h2>

<pre><code>Boolean visible = (Boolean) js.executeScript(

    "return !!(arguments[0].offsetWidth || " +

    "arguments[0].offsetHeight || " +

    "arguments[0].getClientRects().length);",

    element

);</code></pre>

<p>For ordinary Selenium assertions, <code>isDisplayed()</code> is generally simpler. JavaScript inspection is useful when investigating DOM and rendering behavior.</p>

<hr>

<h2>46. Setting an Input Value Using JavaScript</h2>

<pre><code>js.executeScript(

    "arguments[0].value = arguments[1];",

    input,

    "Selenium"

);</code></pre>

<p>This changes the DOM value property, but it may not trigger all the events expected by a JavaScript framework.</p>

<hr>

<h2>47. Why sendKeys() Is Usually Preferred</h2>

<p>For normal text entry, Selenium's <code>sendKeys()</code> better represents user-like keyboard input.</p>

<pre><code>input.sendKeys("Selenium");</code></pre>

<p>Direct JavaScript value assignment should be used only when there is a specific reason and the application behavior has been considered.</p>

<hr>

<h2>48. Triggering Input and Change Events</h2>

<p>If JavaScript must be used to modify an input value, the application may also require input/change events.</p>

<pre><code>js.executeScript(

    "arguments[0].value = arguments[1];" +

    "arguments[0].dispatchEvent(" +

    "new Event('input', {bubbles:true})" +

    ");" +

    "arguments[0].dispatchEvent(" +

    "new Event('change', {bubbles:true})" +

    ");",

    input,

    "Selenium"

);</code></pre>

<p>Framework-specific controls may require different event behavior, so this technique should not be assumed to reproduce every aspect of real keyboard input.</p>

<hr>

<h2>49. Modifying Element Attributes</h2>

<pre><code>js.executeScript(

    "arguments[0].setAttribute('data-test','demo');",

    element

);</code></pre>

<p>Modifying attributes for testing can change application behavior and should therefore be used carefully.</p>

<hr>

<h2>50. Removing an Attribute</h2>

<pre><code>js.executeScript(

    "arguments[0].removeAttribute('disabled');",

    element

);</code></pre>

<p>This should not be used to falsely bypass application restrictions in a functional test unless the specific test objective is to inspect DOM behavior. Removing a disabled state can invalidate the realism of the test.</p>

<hr>

<h2>51. Accessing the Browser Window Object</h2>

<pre><code>Object width = js.executeScript(

    "return window.innerWidth;"

);

 

Object height = js.executeScript(

    "return window.innerHeight;"

);</code></pre>

<hr>

<h2>52. Getting Page Height</h2>

<pre><code>Long height = (Long) js.executeScript(

    "return document.body.scrollHeight;"

);</code></pre>

<hr>

<h2>53. Getting Current Scroll Position</h2>

<pre><code>Long scrollY = (Long) js.executeScript(

    "return window.scrollY;"

);</code></pre>

<hr>

<h2>54. Checking Browser Viewport Size</h2>

<pre><code>Long width = (Long) js.executeScript(

    "return window.innerWidth;"

);

 

Long height = (Long) js.executeScript(

    "return window.innerHeight;"

);</code></pre>

<hr>

<h2>55. Executing Multiple JavaScript Statements</h2>

<pre><code>js.executeScript(

    "arguments[0].style.outline='3px solid red';" +

    "arguments[0].scrollIntoView({block:'center'});",

    element

);</code></pre>

<hr>

<h2>56. Executing a Function</h2>

<pre><code>js.executeScript(

    "return (function(a, b) { return a + b; })(10, 20);"

);</code></pre>

<hr>

<h2>57. Returning Numeric Values</h2>

<pre><code>Long height = (Long) js.executeScript(

    "return document.body.scrollHeight;"

);

 

System.out.println(height);</code></pre>

<hr>

<h2>58. Returning Boolean Values</h2>

<pre><code>Boolean result = (Boolean) js.executeScript(

    "return document.readyState === 'complete';"

);</code></pre>

<hr>

<h2>59. Returning JavaScript Objects</h2>

<p>JavaScriptExecutor can return JavaScript values to Java. Selenium performs the required mapping for supported JavaScript values.</p>

<pre><code>Object result = js.executeScript(

    "return {name:'Selenium', version:4};"

);</code></pre>

<p>For complex JavaScript objects, the exact mapped representation should be handled according to the Selenium version and returned data structure.</p>

<hr>

<h2>60. JavaScriptExecutor and AJAX</h2>

<p>JavaScriptExecutor can inspect browser-side application state, but it should not be treated as a universal AJAX wait mechanism.</p>

<pre><code>User Action

    ↓

JavaScript

    ↓

AJAX / Fetch

    ↓

Server

    ↓

Response

    ↓

DOM Update

    ↓

Selenium Wait</code></pre>

<p>The preferred strategy is usually to wait for the UI state that indicates that the required operation has completed.</p>

<hr>

<h2>61. Waiting for an AJAX Result</h2>

<pre><code>WebDriverWait wait =

    new WebDriverWait(driver, Duration.ofSeconds(15));

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".ajax-result")

    )

);</code></pre>

<hr>

<h2>62. jQuery Active Requests</h2>

<p>Some older applications using jQuery can expose the number of active AJAX requests through <code>jQuery.active</code>.</p>

<pre><code>wait.until(driver -&gt; (Boolean)

    ((JavascriptExecutor) driver).executeScript(

        "return window.jQuery ? jQuery.active === 0 : true;"

    )

);</code></pre>

<p>This should not be used as a generic solution because many modern applications do not use jQuery and may use Fetch, custom networking libraries, or framework-specific mechanisms.</p>

<hr>

<h2>63. Custom JavaScript-Based Wait</h2>

<pre><code>wait.until(driver -&gt; {

    String state = (String)

        ((JavascriptExecutor) driver)

        .executeScript(

            "return document.readyState;"

        );

 

    return "complete".equals(state);

});</code></pre>

<hr>

<h2>64. Waiting for a JavaScript Property</h2>

<pre><code>wait.until(driver -&gt; {

    WebElement button = driver.findElement(

        By.id("submit")

    );

 

    return (Boolean)

        ((JavascriptExecutor) driver).executeScript(

            "return !arguments[0].disabled;",

            button

        );

});</code></pre>

<hr>

<h2>65. Waiting for Application Status</h2>

<pre><code>wait.until(driver -&gt; {

    WebElement status = driver.findElement(

        By.id("status")

    );

 

    return status.isDisplayed()

        &amp;&amp; status.getText().contains("Loaded");

});</code></pre>

<hr>

<h2>66. JavaScriptExecutor with Dynamic Elements</h2>

<p>JavaScriptExecutor can help inspect dynamic elements, but it does not replace proper element synchronization.</p>

<pre><code>WebElement element = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dynamicElement")

    )

);

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);</code></pre>

<hr>

<h2>67. Handling React Re-Rendering</h2>

<p>React applications can replace DOM nodes during re-rendering. A previously stored WebElement may become stale.</p>

<pre><code>By saveButton = By.id("save");

 

WebElement button = wait.until(

    ExpectedConditions.elementToBeClickable(

        saveButton

    )

);

 

button.click();</code></pre>

<p>Using a stable locator and retrieving the current element when needed can help reduce stale-reference problems.</p>

<hr>

<h2>68. Handling Angular Applications</h2>

<p>Angular applications frequently update component state asynchronously. JavaScriptExecutor can be useful for browser-side inspection, but application-specific explicit waits should normally be used for synchronization.</p>

<hr>

<h2>69. Handling Vue Applications</h2>

<p>Vue applications use reactive data binding to update the DOM. Selenium should wait for the visible application state required by the test.</p>

<hr>

<h2>70. JavaScriptExecutor and Single Page Applications</h2>

<p>SPAs may update the browser URL and DOM without performing a traditional full-page navigation.</p>

<pre><code>Click

 ↓

JavaScript Router

 ↓

Route Change

 ↓

API Request

 ↓

Component Render

 ↓

DOM Update</code></pre>

<p>Use JavaScriptExecutor for inspection when necessary, but use explicit waits for application state synchronization.</p>

<hr>

<h2>71. Handling Lazy Loading</h2>

<p>JavaScript applications may load content only when an element approaches the viewport.</p>

<pre><code>js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);

 

wait.until(

    ExpectedConditions.visibilityOf(element)

);</code></pre>

<hr>

<h2>72. Handling Infinite Scroll</h2>

<pre><code>js.executeScript(

    "window.scrollTo(0, document.body.scrollHeight);"

);</code></pre>

<p>After scrolling, wait for the application to add new content instead of immediately assuming that new items are available.</p>

<hr>

<h2>73. JavaScriptExecutor with Modals</h2>

<p>JavaScript can help inspect modal visibility and DOM state.</p>

<pre><code>Boolean visible = (Boolean) js.executeScript(

    "return window.getComputedStyle(arguments[0]).display !== 'none';",

    modal

);</code></pre>

<hr>

<h2>74. JavaScriptExecutor with Iframes</h2>

<p>JavaScriptExecutor does not remove the requirement to switch browsing contexts. Selenium must still switch into an iframe before interacting with elements inside it.</p>

<pre><code>driver.switchTo().frame(frame);

 

WebElement input = driver.findElement(

    By.id("payment")

);

 

input.sendKeys("1234");

 

driver.switchTo().defaultContent();</code></pre>

<hr>

<h2>75. JavaScriptExecutor with Shadow DOM</h2>

<p>Selenium 4 provides Shadow DOM support through <code>getShadowRoot()</code>. JavaScriptExecutor can also be useful for inspection, but native Selenium Shadow DOM support should generally be preferred when it meets the requirement.</p>

<pre><code>WebElement host = driver.findElement(

    By.cssSelector("my-component")

);

 

SearchContext shadowRoot =

    host.getShadowRoot();

 

WebElement button =

    shadowRoot.findElement(

        By.cssSelector("button")

    );

 

button.click();</code></pre>

<hr>

<h2>76. Executing JavaScript in the Current Document</h2>

<pre><code>js.executeScript(

    "return document.body.innerText;"

);</code></pre>

<p>The script runs against the currently selected browsing context.</p>

<hr>

<h2>77. JavaScriptExecutor and Browser Context</h2>

<p>If the driver is switched into an iframe, JavaScript execution operates within that current browsing context.</p>

<pre><code>driver.switchTo().frame(frame);

 

String text = (String) js.executeScript(

    "return document.body.innerText;"

);

 

driver.switchTo().defaultContent();</code></pre>

<hr>

<h2>78. JavaScriptExecutor and Multiple Windows</h2>

<p>JavaScript execution applies to the currently selected window or tab.</p>

<pre><code>driver.switchTo().window(windowHandle);

 

String title = (String) js.executeScript(

    "return document.title;"

);</code></pre>

<hr>

<h2>79. Using JavaScript for Debugging</h2>

<p>JavaScriptExecutor is particularly useful during debugging because it can expose browser-side information that is not directly available through a simple Selenium method.</p>

<pre><code>String readyState = (String) js.executeScript(

    "return document.readyState;"

);

 

String url = (String) js.executeScript(

    "return window.location.href;"

);

 

String title = (String) js.executeScript(

    "return document.title;"

);</code></pre>

<hr>

<h2>80. JavaScriptExecutor Utility Class</h2>

<pre><code>public class JavaScriptUtils {

 

    private final JavascriptExecutor js;

 

    public JavaScriptUtils(WebDriver driver) {

        this.js = (JavascriptExecutor) driver;

    }

 

    public Object execute(

            String script,

            Object... args) {

 

        return js.executeScript(script, args);

    }

 

    public void scrollToElement(

            WebElement element) {

 

        execute(

            "arguments[0].scrollIntoView({block:'center'});",

            element

        );

    }

 

    public void highlight(

            WebElement element) {

 

        execute(

            "arguments[0].style.outline='3px solid red';",

            element

        );

    }

 

    public String getTitle() {

 

        return (String) execute(

            "return document.title;"

        );

    }

 

    public String getUrl() {

 

        return (String) execute(

            "return window.location.href;"

        );

    }

}</code></pre>

<hr>

<h2>81. Using JavaScriptExecutor in Page Object Model</h2>

<pre><code>public class BasePage {

 

    protected WebDriver driver;

    protected WebDriverWait wait;

    protected JavascriptExecutor js;

 

    public BasePage(WebDriver driver) {

 

        this.driver = driver;

 

        this.wait =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(15)

            );

 

        this.js =

            (JavascriptExecutor) driver;

    }

 

    protected void scrollTo(

            WebElement element) {

 

        js.executeScript(

            "arguments[0].scrollIntoView({block:'center'});",

            element

        );

    }

}</code></pre>

<hr>

<h2>82. JavaScriptExecutor in a Login Page</h2>

<pre><code>public class LoginPage {

 

    private WebDriver driver;

    private WebDriverWait wait;

    private JavascriptExecutor js;

 

    private By username =

        By.id("username");

 

    private By password =

        By.id("password");

 

    private By loginButton =

        By.id("login");

 

    public LoginPage(WebDriver driver) {

 

        this.driver = driver;

 

        this.wait =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(15)

            );

 

        this.js =

            (JavascriptExecutor) driver;

    }

 

    public void login(

            String user,

            String pass) {

 

        WebElement userField = wait.until(

            ExpectedConditions.visibilityOfElementLocated(

                username

            )

        );

 

        userField.sendKeys(user);

 

        WebElement passField = wait.until(

            ExpectedConditions.visibilityOfElementLocated(

                password

            )

        );

 

        passField.sendKeys(pass);

 

        WebElement button = wait.until(

            ExpectedConditions.elementToBeClickable(

                loginButton

            )

        );

 

        js.executeScript(

            "arguments[0].scrollIntoView({block:'center'});",

            button

        );

 

        button.click();

    }

}</code></pre>

<hr>

<h2>83. Using JavaScriptExecutor with TestNG</h2>

<pre><code>@Test

public void verifyPageTitle() {

 

    JavascriptExecutor js =

        (JavascriptExecutor) driver;

 

    String title = (String) js.executeScript(

        "return document.title;"

    );

 

    Assert.assertTrue(

        title.contains("Selenium")

    );

}</code></pre>

<hr>

<h2>84. JavaScriptExecutor and Assertions</h2>

<p>JavaScriptExecutor can retrieve browser-side values that can then be validated using TestNG assertions.</p>

<pre><code>Boolean disabled = (Boolean) js.executeScript(

    "return arguments[0].disabled;",

    button

);

 

Assert.assertFalse(disabled);</code></pre>

<hr>

<h2>85. JavaScriptExecutor and Screenshots</h2>

<p>Highlighting an element before taking a screenshot can make debugging easier.</p>

<pre><code>js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

File screenshot =

    ((TakesScreenshot) driver)

        .getScreenshotAs(OutputType.FILE);</code></pre>

<hr>

<h2>86. Temporary Highlighting</h2>

<p>When CSS is changed only for debugging, it is good practice to restore the original style when necessary.</p>

<pre><code>String originalOutline =

    element.getCssValue("outline");

 

js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

// Perform debugging or screenshot operation

 

js.executeScript(

    "arguments[0].style.outline=arguments[1];",

    element,

    originalOutline

);</code></pre>

<hr>

<h2>87. JavaScriptExecutor and Element Coordinates</h2>

<pre><code>Object rect = js.executeScript(

    "var r = arguments[0].getBoundingClientRect();" +

    "return {x:r.x, y:r.y, width:r.width, height:r.height};",

    element

);</code></pre>

<hr>

<h2>88. JavaScriptExecutor for DOM Inspection</h2>

<pre><code>String html = (String) js.executeScript(

    "return arguments[0].outerHTML;",

    element

);

 

System.out.println(html);</code></pre>

<hr>

<h2>89. Reading Parent Element</h2>

<pre><code>WebElement parent = (WebElement) js.executeScript(

    "return arguments[0].parentElement;",

    element

);</code></pre>

<hr>

<h2>90. Reading Child Elements</h2>

<pre><code>Object children = js.executeScript(

    "return arguments[0].children.length;",

    element

);</code></pre>

<hr>

<h2>91. Querying Elements with JavaScript</h2>

<pre><code>WebElement element = (WebElement) js.executeScript(

    "return document.querySelector('#username');"

);</code></pre>

<p>For normal Selenium automation, WebDriver locators such as <code>By.id()</code> and <code>By.cssSelector()</code> are generally preferable because they integrate directly with WebDriver's element APIs and expected conditions.</p>

<hr>

<h2>92. querySelector()</h2>

<pre><code>WebElement button = (WebElement) js.executeScript(

    "return document.querySelector('button[type=submit]');"

);</code></pre>

<hr>

<h2>93. querySelectorAll()</h2>

<pre><code>Object count = js.executeScript(

    "return document.querySelectorAll('.product').length;"

);</code></pre>

<hr>

<h2>94. JavaScriptExecutor and Local Storage</h2>

<p>JavaScript can inspect browser local storage in appropriate test scenarios.</p>

<pre><code>String token = (String) js.executeScript(

    "return window.localStorage.getItem('token');"

);</code></pre>

<p>Accessing or modifying application storage can change application state, so it should be used deliberately and should align with the purpose of the test.</p>

<hr>

<h2>95. Reading Session Storage</h2>

<pre><code>String value = (String) js.executeScript(

    "return window.sessionStorage.getItem('user');"

);</code></pre>

<hr>

<h2>96. Setting Local Storage</h2>

<pre><code>js.executeScript(

    "window.localStorage.setItem('testMode','true');"

);</code></pre>

<p>Storage manipulation is generally more suitable for controlled setup or specialized testing than for simulating normal user behavior.</p>

<hr>

<h2>97. Removing Local Storage Data</h2>

<pre><code>js.executeScript(

    "window.localStorage.removeItem('testMode');"

);</code></pre>

<hr>

<h2>98. Clearing Local Storage</h2>

<pre><code>js.executeScript(

    "window.localStorage.clear();"

);</code></pre>

<hr>

<h2>99. JavaScriptExecutor and Cookies</h2>

<p>Cookies should generally be handled using Selenium's cookie API.</p>

<pre><code>driver.manage().getCookies();</code></pre>

<p>JavaScript cookie access can be useful for browser-side inspection, but it has browser security and scope limitations.</p>

<hr>

<h2>100. JavaScriptExecutor and Security Restrictions</h2>

<p>JavaScript executed through Selenium runs in the browser's page context and is subject to browser security rules such as same-origin restrictions. It should not be assumed that Selenium JavaScript can freely access every external domain, browser process, or protected resource.</p>

<hr>

<h2>101. executeAsyncScript() Example</h2>

<pre><code>JavascriptExecutor js =

    (JavascriptExecutor) driver;

 

Object result = js.executeAsyncScript(

    "var callback = arguments[arguments.length - 1];" +

    "setTimeout(function() {" +

    "callback('Async operation completed');" +

    "}, 1000);"

);

 

System.out.println(result);</code></pre>

<hr>

<h2>102. How executeAsyncScript() Works</h2>

<pre><code>Java

 ↓

executeAsyncScript()

 ↓

JavaScript Starts

 ↓

Asynchronous Operation

 ↓

Callback Called

 ↓

Result Returned to Java</code></pre>

<hr>

<h2>103. Callback in executeAsyncScript()</h2>

<p>The final item in the JavaScript <code>arguments</code> collection is the Selenium-provided callback.</p>

<pre><code>var callback =

    arguments[arguments.length - 1];</code></pre>

<p>Calling the callback signals that the asynchronous JavaScript operation has finished.</p>

<hr>

<h2>104. Example with setTimeout()</h2>

<pre><code>Object result = js.executeAsyncScript(

    "var callback = arguments[arguments.length - 1];" +

    "setTimeout(function() {" +

    "callback(true);" +

    "}, 2000);"

);</code></pre>

<hr>

<h2>105. JavaScriptExecutor with Fetch</h2>

<p>JavaScript can technically initiate browser-side Fetch requests, but using it as a general API-testing replacement is usually not appropriate.</p>

<pre><code>js.executeAsyncScript(

    "var callback = arguments[arguments.length - 1];" +

    "fetch('/api/data')" +

    ".then(function(response) {" +

    "    return response.ok;" +

    "})" +

    ".then(function(result) {" +

    "    callback(result);" +

    "})" +

    ".catch(function() {" +

    "    callback(false);" +

    "});"

);</code></pre>

<p>Such scripts are also subject to browser security and same-origin/CORS behavior. For API testing, dedicated API-testing approaches are generally more appropriate.</p>

<hr>

<h2>106. JavaScriptExecutor and MutationObserver</h2>

<p>In specialized scenarios, a browser-side <code>MutationObserver</code> can observe DOM changes. This can be useful for diagnostics or custom synchronization, but it can also make tests unnecessarily complex.</p>

<pre><code>var observer = new MutationObserver(function(mutations) {

    // Observe DOM changes

});</code></pre>

<p>Prefer simple explicit Selenium waits whenever they can express the required condition.</p>

<hr>

<h2>107. JavaScriptExecutor with Loading Indicators</h2>

<pre><code>wait.until(driver -&gt; {

    WebElement loader = driver.findElement(

        By.cssSelector(".loader")

    );

 

    return !loader.isDisplayed();

});</code></pre>

<p>Alternatively, Selenium's built-in invisibility condition can be used.</p>

<hr>

<h2>108. JavaScriptExecutor and Dynamic Buttons</h2>

<pre><code>WebElement button = wait.until(

    ExpectedConditions.presenceOfElementLocated(

        By.id("submit")

    )

);

 

Boolean enabled = (Boolean) js.executeScript(

    "return !arguments[0].disabled;",

    button

);

 

System.out.println(enabled);</code></pre>

<hr>

<h2>109. JavaScriptExecutor and Read-Only Fields</h2>

<pre><code>Boolean readOnly = (Boolean) js.executeScript(

    "return arguments[0].readOnly;",

    input

);</code></pre>

<hr>

<h2>110. JavaScriptExecutor and Required Fields</h2>

<pre><code>Boolean required = (Boolean) js.executeScript(

    "return arguments[0].required;",

    input

);</code></pre>

<hr>

<h2>111. JavaScriptExecutor and Checked State</h2>

<pre><code>Boolean checked = (Boolean) js.executeScript(

    "return arguments[0].checked;",

    checkbox

);</code></pre>

<hr>

<h2>112. JavaScriptExecutor and Focus</h2>

<pre><code>js.executeScript(

    "arguments[0].focus();",

    input

);</code></pre>

<p>For normal keyboard interaction, Selenium's element interaction APIs should generally remain the preferred approach.</p>

<hr>

<h2>113. JavaScriptExecutor and Blur</h2>

<pre><code>js.executeScript(

    "arguments[0].blur();",

    input

);</code></pre>

<hr>

<h2>114. JavaScriptExecutor and DOM Click Events</h2>

<pre><code>js.executeScript(

    "arguments[0].dispatchEvent(" +

    "new MouseEvent('click', {bubbles:true})" +

    ");",

    element

);</code></pre>

<p>This is different from a normal WebDriver click and should only be used when the test specifically requires browser-side event dispatch.</p>

<hr>

<h2>115. JavaScriptExecutor and Custom Events</h2>

<pre><code>js.executeScript(

    "arguments[0].dispatchEvent(" +

    "new Event('change', {bubbles:true})" +

    ");",

    element

);</code></pre>

<hr>

<h2>116. JavaScriptExecutor and Dynamic Forms</h2>

<p>JavaScriptExecutor can help inspect form properties while Selenium waits for the application to reach the expected state.</p>

<pre><code>Boolean valid = (Boolean) js.executeScript(

    "return arguments[0].checkValidity();",

    form

);</code></pre>

<hr>

<h2>117. Checking HTML5 Form Validity</h2>

<pre><code>Boolean valid = (Boolean) js.executeScript(

    "return arguments[0].checkValidity();",

    input

);</code></pre>

<hr>

<h2>118. Reading Validation Message</h2>

<pre><code>String message = (String) js.executeScript(

    "return arguments[0].validationMessage;",

    input

);</code></pre>

<hr>

<h2>119. JavaScriptExecutor for Debugging Element State</h2>

<pre><code>String state = (String) js.executeScript(

    "return {" +

    "display: getComputedStyle(arguments[0]).display," +

    "visibility: getComputedStyle(arguments[0]).visibility," +

    "disabled: arguments[0].disabled," +

    "value: arguments[0].value" +

    "};",

    element

);</code></pre>

<hr>

<h2>120. Common Exceptions Related to JavaScriptExecutor</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Exception</th><th>Possible Cause</th></tr>

<tr><td>JavascriptException</td><td>Invalid JavaScript or JavaScript execution failure</td></tr>

<tr><td>StaleElementReferenceException</td><td>Element was replaced before execution</td></tr>

<tr><td>WebDriverException</td><td>Browser or WebDriver-level problem</td></tr>

<tr><td>TimeoutException</td><td>Expected condition did not occur</td></tr>

<tr><td>NoSuchElementException</td><td>Element could not be located</td></tr>

<tr><td>ClassCastException</td><td>Returned JavaScript value was cast incorrectly</td></tr>

</table>

<hr>

<h2>121. Handling JavascriptException</h2>

<p>If JavaScript execution fails, verify the JavaScript syntax, the arguments supplied, the current browsing context, the existence of the target element, and the browser state.</p>

<hr>

<h2>122. JavaScriptExecutor and Stale Elements</h2>

<p>JavaScriptExecutor does not eliminate stale element problems. If a WebElement has been replaced by the application, passing that old reference to JavaScript can still result in a stale element error.</p>

<hr>

<h2>123. Re-Locating Before JavaScript Execution</h2>

<pre><code>WebElement button = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.id("save")

    )

);

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    button

);</code></pre>

<hr>

<h2>124. JavaScriptExecutor Best Practice</h2>

<p>Use JavaScriptExecutor as a specialized tool rather than the default mechanism for every Selenium operation.</p>

<pre><code>Preferred:

Selenium API

      ↓

If specialized browser-side operation is required

      ↓

JavaScriptExecutor</code></pre>

<hr>

<h2>125. Best Practice: Prefer WebDriver APIs</h2>

<p>For normal user actions, use Selenium APIs whenever possible.</p>

<pre><code>element.click();

element.sendKeys("Selenium");

element.clear();</code></pre>

<hr>

<h2>126. Best Practice: Use Explicit Waits</h2>

<pre><code>WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(15)

    );

 

WebElement element = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.id("submit")

    )

);</code></pre>

<hr>

<h2>127. Best Practice: Use Stable Locators</h2>

<pre><code>By.id("username")

 

By.cssSelector("[data-testid='login']")

 

By.xpath("//button[normalize-space()='Submit']")</code></pre>

<hr>

<h2>128. Best Practice: Do Not Use JavaScript to Hide Application Bugs</h2>

<p>If a standard click fails, investigate the underlying reason before switching to JavaScript. Automation should expose application problems rather than silently bypassing them.</p>

<hr>

<h2>129. Best Practice: Keep JavaScript Utilities Reusable</h2>

<p>Repeated JavaScript operations should be placed in reusable utility methods.</p>

<pre><code>public void scrollToElement(WebElement element) {

    js.executeScript(

        "arguments[0].scrollIntoView({block:'center'});",

        element

    );

}</code></pre>

<hr>

<h2>130. Best Practice: Keep JavaScript Small and Readable</h2>

<p>Long JavaScript strings inside test cases can make automation difficult to maintain. Keep scripts short, meaningful, and encapsulated in utility methods where appropriate.</p>

<hr>

<h2>131. Best Practice: Validate JavaScript Results</h2>

<pre><code>Boolean enabled = (Boolean) js.executeScript(

    "return !arguments[0].disabled;",

    button

);

 

Assert.assertTrue(enabled);</code></pre>

<hr>

<h2>132. Best Practice: Consider Browser Security</h2>

<p>JavaScriptExecutor runs within the browser environment and remains subject to browser security policies. It should not be treated as a mechanism for bypassing browser security controls.</p>

<hr>

<h2>133. Best Practice: Avoid Excessive DOM Manipulation</h2>

<p>Changing application DOM properties with JavaScript can create a state that a real user could not produce. Such modifications should be limited to appropriate test objectives, diagnostics, or controlled setup.</p>

<hr>

<h2>134. Best Practice: Restore Debugging Changes</h2>

<p>If JavaScript changes an element's style or state only for debugging, restore the original state when the test requires a clean DOM.</p>

<hr>

<h2>135. JavaScriptExecutor Automation Flow</h2>

<pre><code>Start Test

    ↓

Locate Element

    ↓

Wait for Required State

    ↓

Determine Required Operation

    ↓

Use Selenium API

    ↓

If Specialized Browser Operation Is Required

    ↓

Use JavaScriptExecutor

    ↓

Validate Result

    ↓

Continue Test</code></pre>

<hr>

<h2>136. Real-World Example: Scroll and Click</h2>

<pre><code>WebElement checkout = wait.until(

    ExpectedConditions.presenceOfElementLocated(

        By.id("checkout")

    )

);

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    checkout

);

 

wait.until(

    ExpectedConditions.elementToBeClickable(

        By.id("checkout")

    )

).click();</code></pre>

<hr>

<h2>137. Real-World Example: Highlight and Screenshot</h2>

<pre><code>WebElement element = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("confirmation")

    )

);

 

js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

File screenshot =

    ((TakesScreenshot) driver)

        .getScreenshotAs(OutputType.FILE);</code></pre>

<hr>

<h2>138. Real-World Example: Check Page Readiness</h2>

<pre><code>WebDriverWait wait =

    new WebDriverWait(driver, Duration.ofSeconds(15));

 

wait.until(driver -&gt;

    "complete".equals(

        ((JavascriptExecutor) driver)

            .executeScript(

                "return document.readyState;"

            )

    )

);</code></pre>

<hr>

<h2>139. Real-World Example: Read Dynamic Text</h2>

<pre><code>WebElement status = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("status")

    )

);

 

String text = (String) js.executeScript(

    "return arguments[0].textContent;",

    status

);

 

System.out.println(text);</code></pre>

<hr>

<h2>140. Real-World Example: Dynamic Search</h2>

<pre><code>WebElement search = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("search")

    )

);

 

search.sendKeys("Selenium");

 

WebElement result = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".search-result")

    )

);

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    result

);

 

result.click();</code></pre>

<hr>

<h2>141. Real-World Example: Dynamic Dashboard</h2>

<pre><code>WebElement dashboard = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".dashboard")

    )

);

 

String dashboardText = (String) js.executeScript(

    "return arguments[0].innerText;",

    dashboard

);

 

System.out.println(dashboardText);</code></pre>

<hr>

<h2>142. Real-World Example: Infinite Scroll</h2>

<pre><code>int previousCount = 0;

 

for (int i = 0; i &lt; 5; i++) {

 

    js.executeScript(

        "window.scrollTo(0, document.body.scrollHeight);"

    );

 

    wait.until(driver -&gt;

        driver.findElements(

            By.cssSelector(".product-card")

        ).size() &gt; previousCount

    );

 

    previousCount = driver.findElements(

        By.cssSelector(".product-card")

    ).size();

}</code></pre>

<hr>

<h2>143. Real-World Example: Loading Overlay</h2>

<pre><code>wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".loading-overlay")

    )

);

 

WebElement submit = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.id("submit")

    )

);

 

submit.click();</code></pre>

<hr>

<h2>144. Real-World Example: JavaScript-Based Form</h2>

<pre><code>WebElement email = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("email")

    )

);

 

email.sendKeys("[email protected]");

 

WebElement submit = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.id("submit")

    )

);

 

submit.click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".success-message")

    )

);</code></pre>

<hr>

<h2>145. Complete JavaScriptExecutor Example</h2>

<pre><code>import java.time.Duration;

 

import org.openqa.selenium.By;

import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;

 

public class JavaScriptExecutorDemo {

 

    public static void main(String[] args) {

 

        WebDriver driver = new ChromeDriver();

 

        WebDriverWait wait =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(15)

            );

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        try {

 

            driver.get("https://example.com");

 

            wait.until(driver -&gt;

                "complete".equals(

                    js.executeScript(

                        "return document.readyState;"

                    )

                )

            );

 

            String title = (String) js.executeScript(

                "return document.title;"

            );

 

            System.out.println(

                "Page Title: " + title

            );

 

            WebElement element = wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("demo")

                )

            );

 

            js.executeScript(

                "arguments[0].scrollIntoView({block:'center'});",

                element

            );

 

            js.executeScript(

                "arguments[0].style.outline='3px solid red';",

                element

            );

 

        } finally {

 

            driver.quit();

        }

    }

}</code></pre>

<hr>

<h2>146. JavaScriptExecutor vs Selenium WebDriver</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Selenium WebDriver</th><th>JavaScriptExecutor</th></tr>

<tr><td>Designed for browser automation</td><td>Designed for executing JavaScript</td></tr>

<tr><td>Supports user-like interactions</td><td>Provides browser-side scripting</td></tr>

<tr><td>Preferred for normal actions</td><td>Useful for specialized operations</td></tr>

<tr><td>Provides element interaction APIs</td><td>Provides direct JavaScript access</td></tr>

<tr><td>Uses WebDriver interaction model</td><td>Uses browser JavaScript execution</td></tr>

</table>

<hr>

<h2>147. Common Mistakes</h2>

<ul>

<li>Using JavaScript click for every element.</li>

<li>Using JavaScript instead of fixing synchronization.</li>

<li>Using JavaScript to bypass disabled controls without a valid test purpose.</li>

<li>Using long <code>Thread.sleep()</code> statements instead of explicit waits.</li>

<li>Assuming <code>document.readyState</code> means every SPA component is ready.</li>

<li>Ignoring stale element problems.</li>

<li>Using unstable locators.</li>

<li>Ignoring iframe or Shadow DOM boundaries.</li>

<li>Writing large JavaScript strings directly in every test case.</li>

<li>Not validating the result of a JavaScript operation.</li>

</ul>

<hr>

<h2>148. Troubleshooting Table</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Problem</th><th>Possible Reason</th><th>Recommended Approach</th></tr>

<tr><td>JavaScript click fails</td><td>Invalid element or browser state</td><td>Verify locator and element state</td></tr>

<tr><td>Element is stale</td><td>DOM was re-rendered</td><td>Locate the element again</td></tr>

<tr><td>Element cannot be clicked</td><td>Overlay or animation</td><td>Wait for the blocking state to disappear</td></tr>

<tr><td>Input value not recognized</td><td>Framework event not triggered</td><td>Prefer sendKeys or trigger appropriate events</td></tr>

<tr><td>Page is not ready</td><td>Async application work continues</td><td>Wait for application-specific state</td></tr>

<tr><td>Element not found</td><td>Wrong context or dynamic rendering</td><td>Check iframe, shadow DOM, locator and timing</td></tr>

</table>

<hr>

<h2>149. Interview Questions</h2>

<h3>Q1. What is JavaScriptExecutor in Selenium?</h3>

<p>JavaScriptExecutor is a Selenium interface that allows Java-based automation scripts to execute JavaScript in the current browser context.</p>

<h3>Q2. How do you create a JavaScriptExecutor object?</h3>

<pre><code>JavascriptExecutor js =

    (JavascriptExecutor) driver;</code></pre>

<h3>Q3. What is executeScript()?</h3>

<p>It executes JavaScript synchronously in the current browsing context and can return a value to Java.</p>

<h3>Q4. What is executeAsyncScript()?</h3>

<p>It executes asynchronous JavaScript and waits for the JavaScript callback to signal completion.</p>

<h3>Q5. What is arguments[0]?</h3>

<p>It represents the first argument passed from Selenium Java to the JavaScript code.</p>

<h3>Q6. How do you click an element using JavaScript?</h3>

<pre><code>js.executeScript(

    "arguments[0].click();",

    element

);</code></pre>

<h3>Q7. Should JavaScript click be preferred over WebElement.click()?</h3>

<p>No. For normal UI automation, WebElement's Selenium interaction should generally be preferred. JavaScript click is a specialized technique.</p>

<h3>Q8. How do you scroll to an element?</h3>

<pre><code>js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);</code></pre>

<h3>Q9. How do you get the page title using JavaScriptExecutor?</h3>

<pre><code>String title = (String) js.executeScript(

    "return document.title;"

);</code></pre>

<h3>Q10. How do you get the current URL?</h3>

<pre><code>String url = (String) js.executeScript(

    "return window.location.href;"

);</code></pre>

<h3>Q11. How do you check document readiness?</h3>

<pre><code>String state = (String) js.executeScript(

    "return document.readyState;"

);</code></pre>

<h3>Q12. Can JavaScriptExecutor solve StaleElementReferenceException?</h3>

<p>No. If the referenced DOM node has been replaced, the WebElement reference can still be stale. The element normally needs to be located again.</p>

<h3>Q13. Can JavaScriptExecutor handle iframe switching?</h3>

<p>JavaScriptExecutor does not replace Selenium's frame-switching mechanism. Use <code>driver.switchTo().frame()</code> for iframe context switching.</p>

<h3>Q14. Can JavaScriptExecutor access Shadow DOM?</h3>

<p>JavaScript can inspect shadow DOM in appropriate contexts, while Selenium 4 also provides native ShadowRoot support through <code>getShadowRoot()</code>.</p>

<h3>Q15. Why is JavaScriptExecutor useful in debugging?</h3>

<p>It can inspect DOM properties, document state, styles, element coordinates, browser values, and other browser-side information.</p>

<hr>

<h2>150. Quick Revision</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Concept</th><th>Key Point</th></tr>

<tr><td>JavaScriptExecutor</td><td>Executes JavaScript in the browser</td></tr>

<tr><td>executeScript()</td><td>Executes synchronous JavaScript</td></tr>

<tr><td>executeAsyncScript()</td><td>Executes asynchronous JavaScript</td></tr>

<tr><td>arguments[0]</td><td>First argument passed to JavaScript</td></tr>

<tr><td>return</td><td>Returns JavaScript value to Java</td></tr>

<tr><td>JavaScript Click</td><td>DOM-level click operation</td></tr>

<tr><td>scrollIntoView()</td><td>Scrolls an element into the viewport</td></tr>

<tr><td>document.readyState</td><td>Reports document loading state</td></tr>

<tr><td>innerText</td><td>Reads rendered text</td></tr>

<tr><td>textContent</td><td>Reads DOM text content</td></tr>

<tr><td>getAttribute()</td><td>Reads an element attribute</td></tr>

<tr><td>localStorage</td><td>Browser-side storage accessible to page JavaScript</td></tr>

<tr><td>Shadow DOM</td><td>Encapsulated DOM that may require ShadowRoot access</td></tr>

<tr><td>Best Practice</td><td>Prefer Selenium APIs for normal interactions</td></tr>

</table>

<hr>

<h2>151. Final Summary</h2>

<p>JavaScriptExecutor is a powerful Selenium WebDriver feature for executing JavaScript inside the browser. It is particularly useful when testing modern JavaScript-heavy applications, inspecting DOM properties, scrolling to elements, checking browser state, highlighting elements, reading JavaScript properties, and performing specialized browser-side operations.</p>

<p>The most important principle is that JavaScriptExecutor should complement Selenium WebDriver rather than replace it. Normal user interactions should generally use WebDriver APIs such as <code>click()</code>, <code>sendKeys()</code>, and explicit waits. JavaScriptExecutor should be introduced when the test genuinely requires browser-side JavaScript execution or controlled DOM-level inspection or interaction.</p>

<p>For reliable Selenium automation, combine JavaScriptExecutor with stable locators, explicit waits, Page Object Model, proper frame and window handling, Shadow DOM knowledge, dynamic-element strategies, and meaningful assertions.</p>

<p>To learn Selenium WebDriver, Java automation, TestNG, Page Object Model, dynamic elements, browser interactions, automation frameworks, and practical automation workflows, explore the <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training Course</a>.</p>

<p>For course-demo information, visit <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Register for Course Demo</a>.</p>

</div>

Previous Next
whatsapp